package com.xdy.server.core2;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.nio.channels.SocketChannel;

/**
 * @Author: XDY.
 * @Email: 2280944114@qq.com
 * @CreateTime: 2023-03-13  20:19
 * @Description: 资源分发器
 * @Version: 1.0
 */
public class Dispatcher {

    private SocketChannel socketChannel;
    private Request request;
    private Response response;

    public Dispatcher(SocketChannel socketChannel) {
        this.socketChannel = socketChannel;
        this.request = new Request(socketChannel);
        this.response = new Response(socketChannel);
    }

    public void dispatch() {
        try {
            String requestUri = request.getUri();
            if ("/".equals(requestUri)) {
                InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("static/index.html");
                response.print(new String(is.readAllBytes()));
                response.pushToBrowser(200);
                is.close();
            } else {
                Servlet servlet = WebApp.getServletFromUrl(requestUri);
                if (null != servlet) {
                    servlet.service(request, response);
                    response.pushToBrowser(200);
                } else {
                    //查找静态文件，没有找到则404
                    String resource = requestUri.substring(1);
                    InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("static/" + resource);
                    if (null != resourceAsStream) {
                        String extName = resource.substring(resource.lastIndexOf(".") + 1);
                        switch (extName) {
                            case "jpg":
                            case "jpeg":
                            case "png":
                            case "gif":
                            case "ico":
                                response.setContentType("image/jpg;png;gif;x-icon");
                                response.write(resourceAsStream.readAllBytes());
                                break;
                            case "mp3":
                                response.setContentType("audio/mp4");
                                response.write(resourceAsStream.readAllBytes());
                                break;
                            case "mp4":
                                response.setContentType("video/mp4");
                                response.write(resourceAsStream.readAllBytes());
                                break;
                            case "css":
                                response.setContentType("text/css");
                                response.print(new String(resourceAsStream.readAllBytes()));
                                response.pushToBrowser(200);
                                resourceAsStream.close();
                                break;
                            case "js":
                                response.setContentType("application/javascript");
                                response.print(new String(resourceAsStream.readAllBytes()));
                                response.pushToBrowser(200);
                                resourceAsStream.close();
                                break;
                            case "html":
                                response.setContentType("text/html");
                                response.print(new String(resourceAsStream.readAllBytes()));
                                response.pushToBrowser(200);
                                resourceAsStream.close();
                                break;
                            default:
                                if (!resource.endsWith("/")){
                                    response.addHead("Location","http://"+request.getHead("Host")+requestUri+"/");
                                    response.pushToBrowser(301);
                                    return;
                                }
                                InputStream index = Thread.currentThread().getContextClassLoader().getResourceAsStream("static/" + resource + "index.html");
                                if (index != null) {
                                    response.print(new String(index.readAllBytes()));
                                    response.pushToBrowser(200);
                                    index.close();
                                } else {
                                    //返回错误页面
                                    System.err.println("未找到对应资源：" + requestUri);
                                    InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("static/404.html");
                                    response.print(new String(is.readAllBytes()));
                                    response.pushToBrowser(404);
                                    is.close();
                                }
                                break;
                        }
                    } else {
                        //返回错误页面
                        System.err.println("未找到对应资源：" + requestUri);
                        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("static/404.html");
                        response.print(new String(is.readAllBytes()));
                        response.pushToBrowser(404);
                        is.close();
                    }
                }
            }
            //使用短连接，释放资源
            release();
        } catch (IOException e) {
            try {
                response.pushToBrowser(500);
            } catch (IOException ex) {
                e.printStackTrace();
                release();
            }
        }
    }

    /**
     * 释放资源
     */
    private void release() {
        try {
            socketChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
